from pygame.sprite import Sprite  
from pygame.locals import *
from driver import *
from tools import *

class MiniSprite(Sprite):
    """all sprite's super class"""
    def __init__(self, pos, map):
        super(MiniSprite, self).__init__()
        self.image = None
        self.rect = None    # for draw, interger position
        self.pos = list(pos)   # for calc and change value, exact float position
        self.map = map
        self.dirver = Driver()
        self.attr = {}
        
    def update(self):
        super(MiniSprite, self).update()
        self.rect = pygame.Rect((self.pos[0], self.pos[1]), self.rect.size)

################################################
# sprite visual attribute
################################################
class StaticSprite(MiniSprite):
    """sprite's image is static"""
    ATTRNAME = 'static'
    def static__init__(self, image):
        self.attr[StaticSprite.ATTRNAME] = True
        self.image = image # surface
        self.rect = self.image.get_rect(topleft = self.pos)
        
class DynamicSprite(MiniSprite):
    """sprite's image can change"""
    ATTRNAME = 'dynamic'
    def dynamic__init__(self, frame):
        self.attr[DynamicSprite.ATTRNAME] = True
        self.image = frame[0]
        self.rect = self.image.get_rect(topleft = self.pos)
        self.__frame = frame[:] # copy
        
    def animate(self): # change sprite's image
        pass

################################################
# sprite functional attribute
################################################
class MovableSprite(MiniSprite):
    """sprite can move"""
    ATTRNAME = 'movable'
    UP = (0, -1)
    DOWN = (0, 1)
    LEFT = (-1, 0)
    RIGHT = (1, 0)
    def movable__init__(self, speed):
        self.attr[MovableSprite.ATTRNAME] = True
        self.__speed = speed # speed > 0
        self.__lock = False
        self.__distance = 0
        self.__vector = (0, 0)
    
    def move(self, vector, distance):
        if not self.__lock:
            self.__vector = (vector[0] * self.__speed, vector[1] * self.__speed)
            self.__distance = distance
            self.__lock = True

    def move_update(self):
        if self.__lock:
            self.pos[0] += self.__vector[0]
            self.pos[1] += self.__vector[1]
            self.__distance -= (abs(self.__vector[0]) + abs(self.__vector[1])) # simple to clac
            if self.__distance <= 0: self.__lock = False        
        
################################################
# game sprite
################################################
class Tank(DynamicSprite, MovableSprite):
    SPEED = 1
    def __init__(self, pos, map):
        frame = load_frame('tank.bmp', (8, 8), (0, 0, 0))
        super(Tank, self).__init__(pos, map)
        self.dynamic__init__(frame[:8])
        self.movable__init__(Tank.SPEED)

class Player(Tank):
    def update(self):
        # process key signal
        for key in self.dirver.receive(KeySignal.KIND):
            if key.key == K_UP:
                self.dirver.send(GotoSignal(GotoSignal.UP))
            elif key.key == K_DOWN:
                self.dirver.send(GotoSignal(GotoSignal.DOWN))
            elif key.key == K_LEFT:
                self.dirver.send(GotoSignal(GotoSignal.LEFT))
            elif key.key == K_RIGHT:
                self.dirver.send(GotoSignal(GotoSignal.RIGHT))
        # process goto signal
        for goto in self.dirver.receive(GotoSignal.KIND):
            if goto.direct == GotoSignal.UP:
                self.move(MovableSprite.UP, goto.distance)
            elif goto.direct == GotoSignal.DOWN:
                self.move(MovableSprite.DOWN, goto.distance)
            elif goto.direct == GotoSignal.LEFT:
                self.move(MovableSprite.LEFT, goto.distance)
            elif goto.direct == GotoSignal.RIGHT:
                self.move(MovableSprite.RIGHT, goto.distance)
        # process collision signal
        
        
        self.dirver.clear()
        self.move_update()
        super(Player, self).update()

class Enemy(Tank):
    pass

class Block(StaticSprite):
    def __init__(self, pos, map):
        image = load_image('block.bmp')
        super(Block, self).__init__(pos, map)
        self.static__init__(image)





